
#include "aky_program/aky_com_include.h"

#define TAG "app"

extern synwit_sdisp_ops_t g_sdisp_ops;

static void mount_external_fs();
static void user_init();

void on_boot(void)
{    
    // 检测和处理U盘模式
    /** 关闭背光 */
    lcd_backlight_off();
    GPIO_Init(LCDBL_GPIO, LCDBL_PIN, 1, 0, 0, 0);

    app_usbmsc_handler();

    #if (AKY_PRINTF_TO_UART3 == 1)
    aky_uart_3_init();
    #endif
    
    uart_init();

    //挂载flash
    if(SYS->RSTSR & SYS_RSTSR_WDT_Msk)
    {
        SYS->RSTSR = (1 << SYS_RSTSR_WDT_Pos);
        
        printf("WDT Reset Happened\r\n");
        {

            uint32_t n=0;
            SYS->USBPHYCR = 0x000001db;
            SYS->USBCR = 0;
            MSC_Init();
            USBD_Open(); 
            while(1==1)
            { 
                MSC_ProcessOUT();
                
                if(++n % 1000000 == 0)
                {
                    FlashDiskFlush();
                    //350MS
                    usb_time_out++; 


                }
                if (usb_time_out > 3000 / 350)
                {
                    //拔掉usb则跳出
                    break;
                }
            }
            USBD_Close();
            MSC_Init();
            SYS->CLKEN0 &= ~(0x01 << SYS_CLKEN0_USB_Pos); 
            SYS->USBPHYCR = 0x00000042;
            SYS->USBCR = 0;
            g_mount_type = MOUNT_SPI_FLASH;
        
        }    
    }

    char ver[48];
    synwit_ui_get_platform_version_name(ver, sizeof(ver));
    printf("UI platform version: %s\n", ver);
    
    systick_init();

    #if 00
    while (1)
    {
        time_out_test();
        LED_TEST_PIN_FLIP();
    }
    
    #endif
}

void framework_ready(void)
{
    lv_coord_t hres = synwit_ui_manifest_get_int("peripheral.display.hres", 800);
    lv_coord_t vres = synwit_ui_manifest_get_int("peripheral.display.vres", 480);
    int rotation = synwit_ui_manifest_get_int("peripheral.display.rotation", 0);

    lcdc_init();
    peripheral_lcd_init(hres, vres);
    jpeg_init();

    //显示开机logo和开机动画
    bootscreen(hres, vres);
    
    // LVGL硬件相关服务初始化
    lv_port_jpeg_init();
    lv_port_disp_init(hres, vres, rotation);
    lv_port_indev_init();
    if(lv_disp_get_hor_res(NULL) >= 1024 ||
        lv_disp_get_ver_res(NULL) >= 1024) {
            _lv_mem_set_deceleration(1);
    }

    // 挂载外部存储器(TF卡、外接U盘)
    mount_external_fs();
    // UI框架准备就绪后，就可以注册各个界面了
    app_register_screens();
    
    // 执行用户自定义的初始化流程
    user_init();
}

void app_ready(void)
{
    lvgl_layer_init();
    
    bootscreen_cleanup();  //切换到lvgl显存后，再释放动画显存
}

void main_tick(void)
{
    // 主循环回调函数，LVGL主循环运行过程中，会定时/不定时
    // 的调用这个函数
   aky_task_0();
   aky_task_1();
   aky_task_2();
    aky_task_3();
    voice_play_stat_pro();
    syn_mem_to_net_pro();
    /* 串口屏功能——处理串口命令及发送应答 */
    if(g_sdisp_ops.rx_handler) {
        g_sdisp_ops.rx_handler();
    }
}

void on_ezoc_msg(const char *msg, uint32_t len)
{
    /* 串口屏功能——发送通知帧 */
    if(g_sdisp_ops.notify) {
        g_sdisp_ops.notify((const uint8_t *)msg, len);
    }
}

void SysTick_Handler(void)
{
    swm_inctick();
    lv_tick_inc(1);
}

static synwit_app_callback_t s_app_ops = {
    .framework_ready = framework_ready,
    .app_ready = app_ready,
    
    .main_tick = main_tick,
    /* main_tick默认触发间隔为50ms */
    .main_tick_period = 10,
    /* main_tick回调的触发优先级默认为LV_TASK_PRIO_HIGH */
    .main_tick_prio = LV_TASK_PRIO_HIGH,    // LV_TASK_PRIO_HIGHEST
    
    .on_ezoc_msg = on_ezoc_msg,
};

static void mount_external_fs()
{
    static FATFS sd_fatfs;
    
    int enabled_sd = synwit_ui_manifest_get_int("peripheral.storage.sd", 1);
    if(f_mount(&sd_fatfs, "sd:", 1) == FR_OK) 
    {
        printf("sd card mounted\n");
    }
    else
    {
        printf("sd card mount failed\n");
    }

}

static void user_init()
{
    // TODO: 驱动初始化、app全局变量初始化等代码可以添加在这里。
    //（注意：UI对象的创建、加载等不要加在这里，请在对应的screenXXX.c
    // 内进行UI对象的创建及操作）
    aky_func_init();
}

int main()
{   
    MSC_Init();
	SYS->CLKEN0 &= ~(0x01 << SYS_CLKEN0_USB_Pos); 
	SYS->USBPHYCR = 0x00000042;
	SYS->USBCR = 0;
	
    USBD_Close();

    on_boot();

    // 注意! 初始化代码请添加到user_init()函数中而不是这里。因
    // 为执行到这里时，HMI平台还没启动，如果在这里调用任何LVGL
    // 接口，或"synwit_ui_xxxx"类接口，都无法保证能正常执行。
    
    // 启动HMI平台，这个函数会以阻塞模式运行，不会返回。
    synwit_ui_start(NULL, &s_app_ops);
}